import { inputComponents } from "./config"
import store from "@/store"

/**
 * 生成一个永不重复的 key
 * @param { Number } randomLength 
 */
export function getUuiKey(randomLength = 5) {
  return Number(Math.random().toString().substr(2, randomLength) + Date.now()).toString(36)
}

// 给需要添加的控件添加自定义属性,即补充完整属性
export function createFormItem(item) {
  if (!item) return item
  const config = item.__config__ || {};
  config.formId = `field${getUuiKey()}`; // 表单项id
  config.renderKey = `${config.formId}`; // 改变renderKey后可以实现强制更新组件
  if (item.id) item.id = getUuiKey()
  // 根据容器布局类型设置不同的属性
  //  layout 布局型组件
  if (config.tagType == 'layout') {
    // 布局型组件
    config.componentName = config.label || config.componentName;
    !Array.isArray(item.children) && (item.children = []);
    delete config.label; // 布局型组件无需配置label属性
  } else {
    item.__vModel__ = config.formId; // 字段名称
  }

  if (Array.isArray(item.children)) {
    item.children = item.children.map((childItem) =>
      createFormItem(childItem)
    );
  }

  return item;
}
// 更新修改后的表单列表,list-完整表单，value更新的表单项数据
export function updateForm(list, newValue) {
  const formId = newValue.__config__.formId;
  const index = list.findIndex(
    item => item.__config__.formId == formId
  );
  if (index > -1) {
    // 在显示列表中找到选中的表单项,将修改后的内容更新在列表中
    list.splice(index, 1, deepClone(newValue));
  }
}
// 根据不同表单项设置不同样式,isBorder-是否存在边框
export function changClass(item, currentData, formConf,) {
  return {
    "drawing-item-edit": true,
    "drawing-item-hover": true,
    "drawing-row-item":
      formConf.unFocusedComponentBorder &&
      item.__config__.formId != currentData.__config__.formId,
    // "active-from-item":
    //   item.__config__.formId == currentData.__config__.formId &&
    //   !isRowCon,
    "Fg-active": store.state.app.activeId == item.__config__.formId,
  };
}

// 1. 根据是否必填添加对应的必填校验（此处为了错误状态的中文显示）
// 2. 将“正则校验”属性中添加的规则中的字符串转为正则表达式（纯字符串无法识别）
export function formRules(item) {
  if (item.disabled || item.readonly || item.onlyShow) return []
  let ruleList = [];
  // 添加必填的校验文字
  if (item.__config__.required) {
    ruleList.push({ required: true, message: `${item.__config__.label}不能为空` })
  }
  if (item.__config__.regList && item.__config__.regList.length) {
    ruleList = ruleList.concat(formRulesReg(item.__config__.regList))
  }
  return ruleList
}

// 将规则中的字符串转为正则表达式
export function formRulesReg(rules) {
  let ruleList = [];
  rules.forEach(rule => {
    let obj = deepClone(rule);
    let str = rule.pattern;
    if (str[0] == "/" && str[str.length - 1] == "/") {
      str = str.slice(1, str.length - 1);
    }
    // 需要将字符串转为正则字面量，不然无法识别
    obj.pattern = new RegExp(str);
    ruleList.push(obj);
  });
  return ruleList;
}

export function isNumberStr(str) {
  return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str)
}

// 深拷贝对象
export function deepClone(obj) {
  const _toString = Object.prototype.toString

  // null, undefined, non-object, function
  if (!obj || typeof obj !== 'object') {
    return obj
  }

  // DOM Node
  if (obj.nodeType && 'cloneNode' in obj) {
    return obj.cloneNode(true)
  }

  // Date
  if (_toString.call(obj) === '[object Date]') {
    return new Date(obj.getTime())
  }

  // RegExp
  if (_toString.call(obj) === '[object RegExp]') {
    const flags = []
    if (obj.global) { flags.push('g') }
    if (obj.multiline) { flags.push('m') }
    if (obj.ignoreCase) { flags.push('i') }

    return new RegExp(obj.source, flags.join(''))
  }

  const result = Array.isArray(obj) ? [] : obj.constructor ? new obj.constructor() : {}

  for (const key in obj) {
    result[key] = deepClone(obj[key])
  }

  return result
}

// 将一个对象的每一个属性名都转换为驼峰命名，该对象存在多层嵌套
export function toCamelCase(obj) {
  if (typeof obj === 'object' && obj !== null) {
    let newObj = {};
    if (Array.isArray(obj)) {
      newObj = [];
    }

    for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
        const camelCaseKey = toCamelCaseString(key);
        newObj[camelCaseKey] = toCamelCase(obj[key]);
      }
    }

    return newObj;
  } else {
    return obj;
  }
}
// 将字符串转换为驼峰命名法（CamelCase）
export function toCamelCaseString(str) {
  return str.replace(/-([a-z])/g, function (g) {
    return g[1].toUpperCase();
  });
}



//  根据id查找对应树结构节点路径  tree：树结构；id： 对应节点；path：每次保存相应路径的节点
export function getPathById(tree, id, props = { text: 'text', value: 'value', children: 'children' }, path) {
  if (!path) {
    path = []
  }
  for (let i = 0; i < tree.length; i++) {
    let tempPath = [...path]
    tempPath.push(tree[i])
    if (tree[i][props.value] === id) {
      return tempPath
    }
    if (tree[i][props.children]) {
      const reuslt = getPathById(tree[i][props.children], id, props, tempPath)
      if (reuslt) {
        return reuslt
      }
    }
  }
}

// 对文件名进行处理，将文件名称和后缀名分割开
export function formatFile(fileName) {
  let file = {
    name: '',
    ext: '', // 后缀名
    typeName: '', // 后缀名类型名称
  }
  const index = fileName.lastIndexOf('.')
  if (index == -1) {
    file.name = fileName
  } else {
    file.name = fileName.substring(0, index)
    file.ext = fileName.substring(index + 1, fileName.length)
    file.typeName = getFileType(file.ext).name
    file.svg = getFileType(file.ext).svg
  }
  return file
}

// 根据后缀名得到该文件的类型，为文档/图片/音频/视频
export function getFileType(ext) {
  const fileType = [
    {
      name: '文档',
      type: ["doc", "docx"],
      svg: 'word',
    }, {
      name: '表格',
      type: ["xls", "xlsx",],
      svg: 'xlsx'
    }, {
      name: '演示文稿',
      type: ["ppt", "pptx",],
      svg: "ppt",
    }, {
      name: 'pdf',
      type: ["pdf",],
      svg: "pdf",
    }, {
      name: '压缩包',
      type: ["rar", "zip",],
      svg: 'zip'
    },
    {
      name: '图片',
      type: ["jpg", "jpeg", "png", "bmp", "gif"],
      svg: 'png',
    }, {
      name: '视频',
      type: ["mp4", "mov", "wmv", "flv", "avi", "3gp"],
      svg: 'mp4'
    }
  ]
  let type = {
    name: '',
    svg: 'unknow'
  }
  fileType.forEach(el => {
    const index = el.type.findIndex(v => v === ext)
    if (index > -1) {
      type.name = el.name
      type.svg = el.svg
    }
  })

  return type
}
// 遍历树，对树的节点进行操作，该树为数组结构
export function traverseTree(tree, fun) {
  for (let i = 0; i < tree.length; i++) {
    const currentNode = tree[i];
    // 处理当前节点
    if (fun) fun(currentNode)
    // 如果当前节点有子节点，递归遍历子节点
    if (currentNode && Array.isArray(currentNode.children) && currentNode.children.length > 0) {
      traverseTree(currentNode.children, fun);
    }
  }
}
//  去掉树中为null的节点 nodes=Array
export function cleanTree(nodes) {
  return nodes.filter(node => {
    // 如果节点是对象且包含 children 属性，则递归清理
    if (node && typeof node === 'object' && node.children) {
      node.children = cleanTree(node.children); // 递归调用 cleanTree
      return true; // 返回 true 以保留节点
    }
    // 如果节点不是 null，则保留节点
    return node !== null;
  });
}


// 将树结构转为数组
export function treeToArray(tree, children = 'children') {
  let treeData = JSON.parse(JSON.stringify(tree))
  let ary = []
  treeData.forEach(item => {
    if (item[children]) {
      ary.push(item)
      if (item[children].length > 0) {
        ary.push(...treeToArray(item[children], children))
      }
    } else {
      ary.push(item)
    }
    delete item[children]
  })
  return ary
}



export function getOptionsText(defaultValue, options, props = { label: 'label', value: 'value' }) {
  // const options = item.__slot__.options
  // const defaultValue = item.__config__.defaultValue
  let text = ''
  if (defaultValue) {
    const arr = Array.isArray(defaultValue) ? defaultValue : defaultValue.split(",")
    text = options.filter(item => arr.includes(item[props.value])).map(item => item[props.label]).join("，")
  }
  return text
}

// 2. 时间区间
export function getDateText(item) {
  let text = item.__config__.defaultValue
  if (Array.isArray(item.__config__.defaultValue)) {
    text = `${item.__config__.defaultValue[0]} ${item["rangeSeparator"]} ${item.__config__.defaultValue[1]}`
  }
  return text
}

export function formTreeToArray(tree) {
  let treeData = deepClone(tree);
  let ary = [];
  treeData.forEach((item) => {
    if (!item) return
    if (item.children) {
      // ary.push(item);
      if (item.children.length > 0) {
        ary.push(...formTreeToArray(item.children));
      }
    } else {
      ary.push(item);
    }
  });
  return ary;
}

// 表单校验
export function validateForm(data) {
  let errorMsg = [] // 用于存储错误提示
  // 1. 平铺表单，去除行容器
  const list = formTreeToArray(data)
  // 2. 存储所有表单标题 
  // const labels = list.map(item => item.__config__.label)
  list.forEach(item => {
    if (item) {
      const label = item.__config__.label
      // 3-1. 校验标题不能为空
      if (!label) {
        const name = inputComponents.find(itemm => itemm.__config__.tag === item.__config__.tag).__config__.label
        errorMsg.push(`${name}标题不能为空`)
      }
      // 3-2. 表单名称不允许重复
      const labels = list.filter(itemm => itemm.__config__.label === label)
      if (label && labels.length > 1) {
        errorMsg.push(`${label}标题名称重复`)
      }
      // 3.3 多选、单选、下拉选框、级联选择器选项不能为空
      const options = item.__slot__.options || item.options || null
      if (options && options.length === 0) {
        errorMsg.push(`${label}未设置选项`)
      }
    }
  })
  errorMsg = [...new Set(errorMsg)]

  if (errorMsg.length) {
    return { valid: false, errorMsg }
  }
  return { valid: true, errorMsg }
}

// 根据 keyName 求两个数组的交集，keyName为数组内对象的属性名称
export function intersectionFun(arr1, arr2, keyName = 'value') {
  const arr3 = arr1.map(item => item[keyName])
  const arr4 = arr2.filter(x => new Set(arr3).has(x[keyName]))
  return arr4
}

// 根据 keyName 求两个数组的差集，keyName为数组内对象的属性名称
export function differenceSetFun(arr1, arr2, keyName = 'value') {
  let arr3 = arr1.filter(v => {
    return arr2.every(e => e[keyName] != v[keyName]);
  });
  return arr3
}

// 根据 keyName 求两个数组的并集，keyName为数组内对象的属性名称
export function unionFun(arr1, arr2, keyName = 'value') {
  let arr3 = arr1.concat(arr2)
  let obj = []
  let result = arr3.reduce((prev, cur) => {
    obj[cur[keyName]] ? '' : obj[cur[keyName]] = true && prev.push(cur)
    return prev
  }, [])
  return result
}

// 根据key和value将值填入到表单当中
export function setFormValue(list, form) {
  list.forEach(item => {
    if (form && form[item.__config__.formId]) {
      item.__config__.defaultValue = form[item.__config__.formId]
    }
    if (item && item.children && item.children.length) {
      item.children = setFormValue(item.children, form)
    }
  })
  return list
}
// 将object对象转为array的对象
export function objectToArray(object) {
  let array = [];
  for (const key in object) {
    const value = object[key];
    array.push({ key, value, type: typeof value });
  }
  return array;
}
// 将array数据转为object的数据
export function arrayToObject(array) {
  let obj = {}
  for (let index = 0; index < array.length; index++) {
    const element = array[index];
    console.log(element);
    obj[element.key] = element.value
  }
  return obj
}
// 转base64码
export function getBase64(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    let fileResult = "";
    reader.readAsDataURL(file);
    // 开始转
    reader.onload = () => {
      fileResult = reader.result;
    };
    // 转 失败
    reader.onerror = (error) => {
      reject(error);
    };
    // 转 结束
    reader.onloadend = () => {
      resolve(fileResult);
    };
  });
}

// 获取颜色的r/g/b数值
export function getRGBNum(color) {
  const type = detectColorFormat(color)
  let colorObj = {}
  switch (type) {
    case "RGB":
      colorObj = rgbToRGB(color)
      break
    case "HEX":
      colorObj = hexToRGB(color)
      break
    case "HSL":
      break
    default:
      // colorObj = nameToRGB(color)
      break
  }
  return colorObj
}
// color:#fff000
export function hexToRGB(color) {
  const r = parseInt(color.slice(1, 3), 16);
  const g = parseInt(color.slice(3, 5), 16);
  const b = parseInt(color.slice(5, 7), 16);
  return { r, g, b };
}

// color:red
export function nameToRGB(color) {
}
// color:rgb(255,255,0)
export function rgbToRGB(color) {
  // 正则表达式匹配 RGB 格式的颜色字符串
  const rgbRegex = /^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/;
  const matches = color.match(rgbRegex);
  if (matches) {
    return {
      r: parseInt(matches[1], 10),
      g: parseInt(matches[2], 10),
      b: parseInt(matches[3], 10)
    };
  } else {
    throw new Error('Invalid RGB color format');
  }
}

export function detectColorFormat(color) {
  // 正则表达式匹配 RGB 格式
  const rgbRegex = /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/;
  // 正则表达式匹配十六进制格式（包括3位和6位）
  const hexRegex = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
  // 正则表达式匹配 HSL 格式
  const hslRegex = /^hsl\((\d{1,3}),\s*(\d{1,3})%,\s*(\d{1,3})%\)$/;

  if (rgbRegex.test(color)) {
    return 'RGB';
  } else if (hexRegex.test(color)) {
    return 'HEX';
  } else if (hslRegex.test(color)) {
    return 'HSL';
  } else {
    return 'Unknown';
  }
}

export function flattenObject(obj) {
  const result = {};

  function flatten(currentObj, parentKey) {
    for (const key in currentObj) {
      if (currentObj.hasOwnProperty(key)) {
        const fullKey = key;
        if (typeof currentObj[key] === 'object' && currentObj[key] !== null && !Array.isArray(currentObj[key])) {
          flatten(currentObj[key], fullKey);
        } else {
          result[fullKey] = currentObj[key];
        }
      }
    }
  }
  flatten(obj);
  return result;
}

// 合并两个对象，保留两个对象存在值的属性
export function mergeObjects(obj1, obj2) {
  const result = { ...obj1 }; // 创建一个obj1的浅拷贝  
  // 遍历obj2的所有属性  
  for (const key in obj2) {
    if (obj2.hasOwnProperty(key)) {
      // 检查obj2中的属性值是否不是空字符串  
      if (obj2[key] !== "") {
        result[key] = obj2[key]; // 如果不是，则覆盖或添加到结果对象中  
      }
    }
  }
  return result;
}
// 从Base64编码到File对象
export function base64ToFile(dataURL, filename) {
  let arr = dataURL.split(",");
  let youType = arr[0].match(/:(.*?);/)[1];
  let bstr = atob(arr[1]),
    n = bstr.length,
    u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  return new File([u8arr], filename + "." + youType.split("/")[1], {
    type: youType,
  });
}

//数组元素互换位置
export function swapArray(arr, index1, index2) {
  arr[index1] = arr.splice(index2, 1, arr[index1])[0];
  return arr;
}

// 将CSS代码格式的字符串转换为对象
export function cssToObject(cssString) {
  const obj = {};
  const rules = cssString.split(';'); // 分割字符串为规则数组
  rules.forEach(rule => {
    if (rule.trim()) {
      const [property, value] = rule.split(':').map(s => s.trim());
      if (property && value) {
        obj[property] = value;
      }
    }
  });
  return obj;
}

// 将配置的css样式转为代码可识别格式
export function handleStyle(style, fontObj) {
  if (!style) return {}
  const className = style.className
  let styleObj = deepClone(flattenObject(style))
  const cssList = store.state.app.cssList
  const cssSelect = cssList.filter(itemm => className.includes(itemm.name))
  const cssString = cssSelect.map(itemm => itemm.code).join("")
  const cssObject = cssToObject(cssString);
  // 合并对象  
  const mergeObj = mergeObjects(fontObj, mergeObjects(cssObject, styleObj))
  const font = {
    color: mergeObj.color,
    "textAlign": mergeObj.textAlign,
    "lineHeight": mergeObj.lineHeight,
    "fontSize": mergeObj.fontSize,
    "fontWeight": mergeObj.fontWeight,
    "letterSpacing": mergeObj.letterSpacing,
    "textDecorationLine": mergeObj.textDecorationLine,
    "textDecorationColor": mergeObj.textDecorationColor,
    "textDecorationStyle": mergeObj.textDecorationStyle,
  }

  return { ...mergeObj, font }
  // let styleStr1 = cssSelect.map(itemm => itemm.code).join("")
  // const styleStr2 = Object.entries(styleObj)
  //   .map(([key, value]) => `${key}:${value}`)
  //   .join(';');
  // return styleStr1 + styleStr2
}

// 获取当前组件绑定事件的代码  eventName事件名称 event参数 item 组件配置
export function getEventCode() {

}
// 触发自定义事件 eventName事件名称 event参数 item 组件配置,self this指针
export function handleEvent(eventName, event, item, self) {
  if (item && item.event) {
    const eventList = store.state.app.eventList // 全局事件列表
    let eventFun = deepClone(item.event)
    // 获取选中的全局事件
    const eventSelect = eventList.filter(itemm => eventFun.eventName.includes(itemm.name))
    eventSelect.forEach(item => {
      eventFun[item.name].code = eventFun[item.name].code || item.code
    })
    // console.log(eventName, event, eventFun);
    if (eventFun && eventFun[eventName]) {
      // name:方法名 params:参数 code 方法执行代码
      const { name, params, code } = eventFun[eventName] || {};
      if (code) {
        // 使用 new Function 执行传入的代码字符串
        const func = new Function(params, code);
        func.call(self, event);
        // console.log("🚀 ~ ~ ", item.__config__.label, " ~ ~ 🚀")
        // func(event);
      }
    }
  }
}
